/*  GRUPO 25 _ 4421774 - 4439302 - 4468285 - 4141006    */

#include "Fecha.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>


Fecha::Fecha(){
	dia=1;
	mes=1;
	anio=1;
};

Fecha::Fecha(int d, int m, int a){
	if ((d >= 1) && (d <= 30) && (m >= 1) && (m <= 12) && (a >=0)){
		dia=d;
		mes=m;
		anio=a;
	}
	else{
		throw out_of_range("parametros fuera de rango");

	};


};

Fecha::Fecha(const Fecha & f){
	dia= f.dia;
	mes= f.mes;
	anio= f.anio;
};

Fecha::~Fecha(){
};

int Fecha::getDia()const{
	return dia;
};

int Fecha::getMes()const{
	return mes;
};

int Fecha::getAnio()const{
	return anio;
};

void Fecha::setDia(int d){
	if ( (d <= 30) && (d >=1) )
		this->dia = d;
	else
		throw out_of_range("dia fuera de rango");
};

void Fecha::setMes(int m){
	if ((m <= 12) && (m >= 1))
		this->mes = m;
	else
		throw out_of_range("mes fuera de rango");

};

void Fecha::setAnio(int a){
	if (a >= 0)
		this->anio = a;
	else
		throw out_of_range("anio fuera de rango");
};

void Fecha::operator=(const Fecha &f){

	    dia= f.dia;
        mes= f.mes;
        anio= f.anio;

};

Fecha Fecha::operator+(int n){

	Fecha f;
	f.dia= (dia + n) % 30;
	if (f.dia==0){
		f.dia=30;
	}
	int res= (dia+n) / 30;
	if (((dia + n) % 30)==0)
		res = res-1;

	f.mes= (mes + res) % 12;
	if (f.mes==0){
			f.mes=12;
	}

	int res1= (mes+res)/12;
	if (((mes+res)%12)==0)
		res1=res1-1;

	f.anio= anio + res1;

	return f;

};

Fecha Fecha::operator-(int n){
    Fecha f ;

    int a= anio - (n/360);
    int m = mes - ((n%360)/30);
    int d = dia - ((n%360)%30);

    if (d <=0){
        d= 30 + d;
        m= m - 1;
    };
    if (m <=0){
        m= 12 + m;
        a= a-1;
    };
    if(a>=0){
        f.dia = d;
        f.mes = m;
        f.anio = a;
    }else throw out_of_range("Fecha fuera de rango");

    return f;
};

bool Fecha::operator==(const Fecha & f){

	return ((f.dia == dia) && (f.mes == mes) && (f.anio == anio));
};

bool Fecha::operator<(const Fecha & f){
//Devuelve true si la fecha de la clase es menor que la fecha f, de lo contrario,
//devuelve false

	int resDia = f.dia - dia;
	int resMes = f.mes - mes;
	int resAnio = f.anio- anio;
	if (resAnio > 0)
		return true;
	else
		if (resAnio < 0)
			return false;
		else
			if (resMes > 0)
				return true;
			else
				if (resMes < 0)
					return false;
				else
					if (resDia > 0)
						return true;
					else
						return false;

};

bool Fecha::operator>(const Fecha & f){
	return (!(*this == f) && !(*this < f));

};

ostream & operator<<(ostream & o,const Fecha & f){
	o << f.getDia()<< "/" << f.getMes() << "/" << f.getAnio();

	return o;
};

istream & operator>>(istream & in, Fecha & f){
	int d,m,a;
	char t;
	in >> d >> t >> m >> t >> a;
try{
	f.setDia(d);
	f.setMes(m);
	f.setAnio(a);
}
	catch (out_of_range& oor){
                        cerr << "Out of range error: "<< oor.what() << endl;
                    }


	return in;
};

Fecha  operator+(int n ,const Fecha & f2){
	Fecha f= Fecha();
		f.setDia((f2.getDia() + n) % 30);
		if (f.getDia()==0){
			f.setDia(30);
		}

		int res= (f2.getDia()+n) / 30;
		if (((f2.getDia() + n) % 30)==0)
			res = res-1;

		f.setMes((f2.getMes() + res) % 12);
		if (f.getMes()==0){
				f.setMes(12);
		}
		int mAux = f2.getMes();
		int res1= (mAux +res)/12;
		if (((f2.getMes()+res)%12)==0)
			res1=res1-1;

		f.setAnio(f2.getAnio() + res1);

		return f;

};
Fecha operator-(int n,const Fecha & f2){

    Fecha f ;

	    int a= f2.getAnio()- (n/360);
	    int m= f2.getMes() - ((n%360)/30);
	    int d= f2.getDia() - ((n%360)%30);

	    if (d <=0){
            d= 30 + d;
            m= m - 1;
        };
        if (m <=0){
            m= 12 + m;
            a= a-1;
        };
        if(a>=0){
            f.setDia(d);
            f.setMes(m);
            f.setAnio(a);
        }else throw out_of_range("Fecha fuera de rango");

	    return f;
	};
